using System;
using System.Globalization;
using System.Runtime.InteropServices;
using PickGold.Charting;

namespace PickGold.Charting.Formulas
{
	internal class StatisticalAnalysis : IFormula
	{
		private void Anova(double[][] inputValues, out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num2;
			if (inputValues.Length < 3)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesNotEnoughInputSeries);
			}
			outLabels = null;
			for (int i = 0; i < (inputValues.Length - 1); i++)
			{
				if (inputValues[i].Length != inputValues[i + 1].Length)
				{
					throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAnovaTest);
				}
			}
			try
			{
				num2 = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			if ((num2 < 0.0) || (num2 > 1.0))
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			outputValues = new double[2][];
			outLabels = new string[][] { new string[10] };
			outputValues[0] = new double[10];
			outputValues[1] = new double[10];
			int num3 = inputValues.Length - 1;
			int length = inputValues[0].Length;
			double[] values = new double[num3];
			double[] numArray2 = new double[num3];
			for (int j = 0; j < num3; j++)
			{
				values[j] = this.Mean(inputValues[j + 1]);
			}
			for (int k = 0; k < num3; k++)
			{
				numArray2[k] = this.Variance(inputValues[k + 1], true);
			}
			double num7 = this.Mean(values);
			double num8 = 0.0;
			foreach (double num9 in values)
			{
				num8 += (num9 - num7) * (num9 - num7);
			}
			num8 /= (double)(num3 - 1);
			double num10 = this.Mean(numArray2);
			double num11 = (num8 * length) / num10;
			double num12 = 0.0;
			for (int m = 0; m < num3; m++)
			{
				foreach (double num14 in inputValues[m + 1])
				{
					num12 += num14;
				}
			}
			num12 /= (double)(num3 * length);
			double num15 = 0.0;
			for (int n = 0; n < num3; n++)
			{
				num15 += (values[n] - num12) * (values[n] - num12);
			}
			num15 *= length;
			double num17 = 0.0;
			for (int num18 = 0; num18 < num3; num18++)
			{
				foreach (double num19 in inputValues[num18 + 1])
				{
					num17 += (num19 - values[num18]) * (num19 - values[num18]);
				}
			}
			outLabels[0][0] = SR.LabelStatisticalSumOfSquaresBetweenGroups;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = num15;
			outLabels[0][1] = SR.LabelStatisticalSumOfSquaresWithinGroups;
			outputValues[0][1] = 2.0;
			outputValues[1][1] = num17;
			outLabels[0][2] = SR.LabelStatisticalSumOfSquaresTotal;
			outputValues[0][2] = 3.0;
			outputValues[1][2] = num15 + num17;
			outLabels[0][3] = SR.LabelStatisticalDegreesOfFreedomBetweenGroups;
			outputValues[0][3] = 4.0;
			outputValues[1][3] = num3 - 1;
			outLabels[0][4] = SR.LabelStatisticalDegreesOfFreedomWithinGroups;
			outputValues[0][4] = 5.0;
			outputValues[1][4] = num3 * (length - 1);
			outLabels[0][5] = SR.LabelStatisticalDegreesOfFreedomTotal;
			outputValues[0][5] = 6.0;
			outputValues[1][5] = (num3 * length) - 1;
			outLabels[0][6] = SR.LabelStatisticalMeanSquareVarianceBetweenGroups;
			outputValues[0][6] = 7.0;
			outputValues[1][6] = num15 / ((double)(num3 - 1));
			outLabels[0][7] = SR.LabelStatisticalMeanSquareVarianceWithinGroups;
			outputValues[0][7] = 8.0;
			outputValues[1][7] = num17 / ((double)(num3 * (length - 1)));
			outLabels[0][8] = SR.LabelStatisticalFRatio;
			outputValues[0][8] = 9.0;
			outputValues[1][8] = num11;
			outLabels[0][9] = SR.LabelStatisticalFCriteria;
			outputValues[0][9] = 10.0;
			outputValues[1][9] = this.FDistributionInverse(num2, num3 - 1, num3 * (length - 1));
		}

		private void Average(double[][] inputValues, out double[][] outputValues, out string[][] outLabels)
		{
			outLabels = null;
			if (inputValues.Length != 2)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidSeriesNumber);
			}
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalAverage;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.Mean(inputValues[1]);
		}

		private double BetaCF(double a, double b, double x)
		{
			int num = 100;
			double num2 = 3E-07;
			double num3 = 1E-30;
			double num11 = a + b;
			double num13 = a + 1.0;
			double num12 = a - 1.0;
			double num7 = 1.0;
			double num8 = 1.0 - ((num11 * x) / num13);
			if (Math.Abs(num8) < num3)
			{
				num8 = num3;
			}
			num8 = 1.0 / num8;
			double num10 = num8;
			int num4 = 1;
			while (num4 <= num)
			{
				int num5 = 2 * num4;
				double num6 = ((num4 * (b - num4)) * x) / ((num12 + num5) * (a + num5));
				num8 = 1.0 + (num6 * num8);
				if (Math.Abs(num8) < num3)
				{
					num8 = num3;
				}
				num7 = 1.0 + (num6 / num7);
				if (Math.Abs(num7) < num3)
				{
					num7 = num3;
				}
				num8 = 1.0 / num8;
				num10 *= num8 * num7;
				num6 = ((-(a + num4) * (num11 + num4)) * x) / ((a + num5) * (num13 + num5));
				num8 = 1.0 + (num6 * num8);
				if (Math.Abs(num8) < num3)
				{
					num8 = num3;
				}
				num7 = 1.0 + (num6 / num7);
				if (Math.Abs(num7) < num3)
				{
					num7 = num3;
				}
				num8 = 1.0 / num8;
				double num9 = num8 * num7;
				num10 *= num9;
				if (Math.Abs((double)(num9 - 1.0)) < num2)
				{
					break;
				}
				num4++;
			}
			if (num4 > num)
			{
				throw new InvalidOperationException(SR.ExceptionStatisticalAnalysesIncompleteBetaFunction);
			}
			return num10;
		}

		private double BetaFunction(double m, double n)
		{
			return Math.Exp((this.GammLn(m) + this.GammLn(n)) - this.GammLn(m + n));
		}

		private void BetaFunction(out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			double num2;
			try
			{
				num = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			try
			{
				num2 = double.Parse(parameterList[1], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalBetaFunction;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.BetaFunction(num, num2);
		}

		private double BetaIncomplete(double a, double b, double x)
		{
			double num;
			if ((x < 0.0) || (x > 1.0))
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidInputParameter);
			}
			if ((x == 0.0) || (x == 1.0))
			{
				num = 0.0;
			}
			else
			{
				num = Math.Exp((((this.GammLn(a + b) - this.GammLn(a)) - this.GammLn(b)) + (a * Math.Log(x))) + (b * Math.Log(1.0 - x)));
			}
			if (x < ((a + 1.0) / ((a + b) + 2.0)))
			{
				return ((num * this.BetaCF(a, b, x)) / a);
			}
			return (1.0 - ((num * this.BetaCF(b, a, 1.0 - x)) / b));
		}

		private void CheckNumOfPoints(double[][] inputValues)
		{
			if (inputValues[1].Length < 2)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesNotEnoughDataPoints);
			}
			if ((inputValues.Length > 2) && (inputValues[2].Length < 2))
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesNotEnoughDataPoints);
			}
		}

		private void Correlation(double[][] inputValues, out double[][] outputValues, out string[][] outLabels)
		{
			if (inputValues.Length != 3)
			{
				throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			double num = this.Covar(inputValues[1], inputValues[2]);
			double num2 = this.Variance(inputValues[1], false);
			double num3 = this.Variance(inputValues[2], false);
			double num4 = num / Math.Sqrt(num2 * num3);
			outLabels[0][0] = SR.LabelStatisticalCorrelation;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = num4;
		}

		private double Covar(double[] arrayX, double[] arrayY)
		{
			if (arrayX.Length != arrayY.Length)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesCovariance);
			}
			double[] values = new double[arrayX.Length];
			for (int i = 0; i < arrayX.Length; i++)
			{
				values[i] = arrayX[i] * arrayY[i];
			}
			double num2 = this.Mean(values);
			double num3 = this.Mean(arrayX);
			double num4 = this.Mean(arrayY);
			return (num2 - (num3 * num4));
		}

		private void Covariance(double[][] inputValues, out double[][] outputValues, out string[][] outLabels)
		{
			if (inputValues.Length != 3)
			{
				throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			double num = this.Covar(inputValues[1], inputValues[2]);
			outLabels[0][0] = SR.LabelStatisticalCovariance;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = num;
		}

		private void FDistribution(out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			int num2;
			int num3;
			try
			{
				num = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidTValue);
			}
			try
			{
				num2 = int.Parse(parameterList[1], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			try
			{
				num3 = int.Parse(parameterList[2], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalProbability;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.FDistribution(num, num2, num3);
		}

		private double FDistribution(double x, int freedom1, int freedom2)
		{
			if (x < 0.0)
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidTValue);
			}
			if (freedom1 <= 0)
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			if (freedom2 <= 0)
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			if (x == 0.0)
			{
				return 1.0;
			}
			if (x == double.PositiveInfinity)
			{
				return 0.0;
			}
			return this.BetaIncomplete(((double)freedom2) / 2.0, ((double)freedom1) / 2.0, ((double)freedom2) / (freedom2 + (freedom1 * x)));
		}

		private double FDistributionInverse(double probability, int m, int n)
		{
			if (probability == 0.0)
			{
				return double.PositiveInfinity;
			}
			if (probability == 1.0)
			{
				return 0.0;
			}
			if ((probability < 0.0) || (probability > 1.0))
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidProbabilityValue);
			}
			int step = 0;
			return this.FDistributionSearch(probability, m, n, step, 0.0, 10000.0);
		}

		private void FDistributionInverse(out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			int num2;
			int num3;
			try
			{
				num = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidProbabilityValue);
			}
			try
			{
				num2 = int.Parse(parameterList[1], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			try
			{
				num3 = int.Parse(parameterList[2], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalProbability;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.FDistributionInverse(num, num2, num3);
		}

		private double FDistributionSearch(double probability, int m, int n, int step, double start, double end)
		{
			step++;
			double x = (start + end) / 2.0;
			double num2 = this.FDistribution(x, m, n);
			if (step > 30)
			{
				return x;
			}
			if (num2 <= probability)
			{
				return this.FDistributionSearch(probability, m, n, step, start, x);
			}
			return this.FDistributionSearch(probability, m, n, step, x, end);
		}

		public virtual void Formula(string formulaName, double[][] inputValues, out double[][] outputValues, string[] parameterList, string[] extraParameterList, out string[][] outLabels)
		{
			outLabels = null;
			string name = formulaName.ToUpper(CultureInfo.InvariantCulture);
			try
			{
				switch (name)
				{
					case "TTESTEQUALVARIANCES":
						this.TTest(inputValues, out outputValues, parameterList, out outLabels, true);
						return;

					case "TTESTUNEQUALVARIANCES":
						this.TTest(inputValues, out outputValues, parameterList, out outLabels, false);
						return;

					case "TTESTPAIRED":
						this.TTestPaired(inputValues, out outputValues, parameterList, out outLabels);
						return;

					case "ZTEST":
						this.ZTest(inputValues, out outputValues, parameterList, out outLabels);
						return;

					case "FTEST":
						this.FTest(inputValues, out outputValues, parameterList, out outLabels);
						return;

					case "COVARIANCE":
						this.Covariance(inputValues, out outputValues, out outLabels);
						return;

					case "CORRELATION":
						this.Correlation(inputValues, out outputValues, out outLabels);
						return;

					case "ANOVA":
						this.Anova(inputValues, out outputValues, parameterList, out outLabels);
						return;

					case "TDISTRIBUTION":
						this.TDistribution(out outputValues, parameterList, out outLabels);
						return;

					case "FDISTRIBUTION":
						this.FDistribution(out outputValues, parameterList, out outLabels);
						return;

					case "NORMALDISTRIBUTION":
						this.NormalDistribution(out outputValues, parameterList, out outLabels);
						return;

					case "INVERSETDISTRIBUTION":
						this.TDistributionInverse(out outputValues, parameterList, out outLabels);
						return;

					case "INVERSEFDISTRIBUTION":
						this.FDistributionInverse(out outputValues, parameterList, out outLabels);
						return;

					case "INVERSENORMALDISTRIBUTION":
						this.NormalDistributionInverse(out outputValues, parameterList, out outLabels);
						return;

					case "MEAN":
						this.Average(inputValues, out outputValues, out outLabels);
						return;

					case "VARIANCE":
						this.Variance(inputValues, out outputValues, parameterList, out outLabels);
						return;

					case "MEDIAN":
						this.Median(inputValues, out outputValues, out outLabels);
						return;

					case "BETAFUNCTION":
						this.BetaFunction(out outputValues, parameterList, out outLabels);
						return;

					case "GAMMAFUNCTION":
						this.GammaFunction(out outputValues, parameterList, out outLabels);
						return;
				}
				outputValues = null;
			}
			catch (IndexOutOfRangeException)
			{
				throw new InvalidOperationException(SR.ExceptionFormulaInvalidPeriod(name));
			}
			catch (OverflowException)
			{
				throw new InvalidOperationException(SR.ExceptionFormulaNotEnoughDataPoints(name));
			}
		}

		private void FTest(double[][] inputValues, out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			double num7;
			double num8;
			if (inputValues.Length != 3)
			{
				throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays);
			}
			outLabels = null;
			this.CheckNumOfPoints(inputValues);
			try
			{
				num = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			if ((num < 0.0) || (num > 1.0))
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			outputValues = new double[2][];
			outLabels = new string[][] { new string[7] };
			outputValues[0] = new double[7];
			outputValues[1] = new double[7];
			double num2 = this.Variance(inputValues[1], true);
			double num3 = this.Variance(inputValues[2], true);
			double num4 = this.Mean(inputValues[1]);
			double num5 = this.Mean(inputValues[2]);
			double x = num2 / num3;
			if (num3 == 0.0)
			{
				throw new InvalidOperationException(SR.ExceptionStatisticalAnalysesZeroVariance);
			}
			if (x <= 1.0)
			{
				num7 = this.FDistributionInverse((double)(1.0 - num), (int)(inputValues[1].Length - 1), (int)(inputValues[2].Length - 1));
				num8 = 1.0 - this.FDistribution(x, inputValues[1].Length - 1, inputValues[2].Length - 1);
			}
			else
			{
				num7 = this.FDistributionInverse(num, inputValues[1].Length - 1, inputValues[2].Length - 1);
				num8 = this.FDistribution(x, inputValues[1].Length - 1, inputValues[2].Length - 1);
			}
			outLabels[0][0] = SR.LabelStatisticalTheFirstGroupMean;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = num4;
			outLabels[0][1] = SR.LabelStatisticalTheSecondGroupMean;
			outputValues[0][1] = 2.0;
			outputValues[1][1] = num5;
			outLabels[0][2] = SR.LabelStatisticalTheFirstGroupVariance;
			outputValues[0][2] = 3.0;
			outputValues[1][2] = num2;
			outLabels[0][3] = SR.LabelStatisticalTheSecondGroupVariance;
			outputValues[0][3] = 4.0;
			outputValues[1][3] = num3;
			outLabels[0][4] = SR.LabelStatisticalFValue;
			outputValues[0][4] = 5.0;
			outputValues[1][4] = x;
			outLabels[0][5] = SR.LabelStatisticalPFLessEqualSmallFOneTail;
			outputValues[0][5] = 6.0;
			outputValues[1][5] = num8;
			outLabels[0][6] = SR.LabelStatisticalFCriticalValueOneTail;
			outputValues[0][6] = 7.0;
			outputValues[1][6] = num7;
		}

		private void GammaFunction(out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			try
			{
				num = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidInputParameter);
			}
			if (num < 0.0)
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesGammaBetaNegativeParameters);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalGammaFunction;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = Math.Exp(this.GammLn(num));
		}

		private double GammLn(double n)
		{
			double num;
			double[] numArray = new double[] { 76.180091729471457, -86.505320329416776, 24.014098240830911, -1.231739572450155, 0.001208650973866179, -5.395239384953E-06 };
			if (n < 0.0)
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesGammaBetaNegativeParameters);
			}
			double num2 = num = n;
			double d = num + 5.5;
			d -= (num + 0.5) * Math.Log(d);
			double num4 = 1.0000000001900149;
			for (int i = 0; i <= 5; i++)
			{
				num4 += numArray[i] / ++num2;
			}
			return (-d + Math.Log((2.5066282746310007 * num4) / num));
		}

		private double Mean(double[] values)
		{
			if (values.Length == 0)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMeanConditions);
			}
			double num = 0.0;
			foreach (double num2 in values)
			{
				num += num2;
			}
			return (num / ((double)values.Length));
		}

		private double Median(double[] values)
		{
			if (values.Length == 0)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMedianConditions);
			}
			this.Sort(ref values);
			int index = values.Length / 2;
			if ((values.Length % 2) == 0)
			{
				return ((values[index - 1] + values[index]) / 2.0);
			}
			return values[index];
		}

		private void Median(double[][] inputValues, out double[][] outputValues, out string[][] outLabels)
		{
			outLabels = null;
			if (inputValues.Length != 2)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidSeriesNumber);
			}
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalMedian;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.Median(inputValues[1]);
		}

		private double NormalDistribution(double zValue)
		{
			double[] numArray = new double[] { 0.31938153, -0.356563782, 1.781477937, -1.821255978, 1.330274429 };
			if (zValue < -7.0)
			{
				return (this.NormalDistributionFunction(zValue) / Math.Sqrt(1.0 + (zValue * zValue)));
			}
			if (zValue > 7.0)
			{
				return (1.0 - this.NormalDistribution(-zValue));
			}
			double num = 0.2316419;
			num = 1.0 / (1.0 + (num * Math.Abs(zValue)));
			num = 1.0 - (this.NormalDistributionFunction(zValue) * (num * (numArray[0] + (num * (numArray[1] + (num * (numArray[2] + (num * (numArray[3] + (num * numArray[4]))))))))));
			if (zValue <= 0.0)
			{
				num = 1.0 - num;
			}
			return num;
		}

		private void NormalDistribution(out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			try
			{
				num = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidZValue);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalProbability;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.NormalDistribution(num);
		}

		private double NormalDistributionFunction(double t)
		{
			return (0.398942280401433 * Math.Exp((-t * t) / 2.0));
		}

		private double NormalDistributionInverse(double probability)
		{
			double num2;
			if ((probability < 1E-05) || (probability > 0.99999))
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesNormalInvalidProbabilityValue);
			}
			double[] numArray = new double[] { 2.50662823884, -18.61500062529, 41.39119773534, -25.44106049637 };
			double[] numArray2 = new double[] { -8.4735109309, 23.08336743743, -21.06224101826, 3.13082909833 };
			double[] numArray3 = new double[] { 0.3374754822726147, 0.9761690190917186, 0.1607979714918209, 0.0276438810333863, 0.0038405729373609, 0.0003951896511919, 3.21767881768E-05, 2.888167364E-07, 3.960315187E-07 };
			double num = probability - 0.5;
			if (Math.Abs(num) < 0.42)
			{
				num2 = num * num;
				return ((num * ((((((numArray[3] * num2) + numArray[2]) * num2) + numArray[1]) * num2) + numArray[0])) / ((((((((numArray2[3] * num2) + numArray2[2]) * num2) + numArray2[1]) * num2) + numArray2[0]) * num2) + 1.0));
			}
			num2 = probability;
			if (num > 0.0)
			{
				num2 = 1.0 - probability;
			}
			num2 = Math.Log(-Math.Log(num2));
			num2 = numArray3[0] + (num2 * (numArray3[1] + (num2 * (numArray3[2] + (num2 * (numArray3[3] + (num2 * (numArray3[4] + (num2 * (numArray3[5] + (num2 * (numArray3[6] + (num2 * (numArray3[7] + (num2 * numArray3[8])))))))))))))));
			if (num < 0.0)
			{
				num2 = -num2;
			}
			return num2;
		}

		private void NormalDistributionInverse(out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			try
			{
				num = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalProbability;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.NormalDistributionInverse(num);
		}

		private void Sort(ref double[] values)
		{
			for (int i = 0; i < values.Length; i++)
			{
				for (int j = i + 1; j < values.Length; j++)
				{
					if (values[i] > values[j])
					{
						double num = values[i];
						values[i] = values[j];
						values[j] = num;
					}
				}
			}
		}

		private double StudentsDistribution(double tValue, int n, bool oneTailed)
		{
			tValue = Math.Abs(tValue);
			if (n > 300)
			{
				n = 300;
			}
			if (n < 1)
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesStudentsNegativeFreedomDegree);
			}
			double num = 1.0 - this.BetaIncomplete(((double)n) / 2.0, 0.5, ((double)n) / (n + (tValue * tValue)));
			if (oneTailed)
			{
				return ((1.0 - num) / 2.0);
			}
			return (1.0 - num);
		}

		private double StudentsDistributionInverse(double probability, int n)
		{
			if (probability == 0.0)
			{
				return double.PositiveInfinity;
			}
			if (probability == 1.0)
			{
				return 0.0;
			}
			if ((probability < 0.0) || (probability > 1.0))
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidProbabilityValue);
			}
			int step = 0;
			return this.StudentsDistributionSearch(probability, n, step, 0.0, 100000.0);
		}

		private double StudentsDistributionSearch(double probability, int n, int step, double start, double end)
		{
			step++;
			double tValue = (start + end) / 2.0;
			double num2 = this.StudentsDistribution(tValue, n, false);
			if (step > 100)
			{
				return tValue;
			}
			if (num2 <= probability)
			{
				return this.StudentsDistributionSearch(probability, n, step, start, tValue);
			}
			return this.StudentsDistributionSearch(probability, n, step, tValue, end);
		}

		private void TDistribution(out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			int num2;
			int num3;
			try
			{
				num = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidTValue);
			}
			try
			{
				num2 = int.Parse(parameterList[1], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			try
			{
				num3 = int.Parse(parameterList[2], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidTailedParameter);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalProbability;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.StudentsDistribution(num, num2, num3 == 1);
		}

		private void TDistributionInverse(out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			int num2;
			try
			{
				num = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidProbabilityValue);
			}
			try
			{
				num2 = int.Parse(parameterList[1], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidDegreeOfFreedom);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalProbability;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.StudentsDistributionInverse(num, num2);
		}

		private void TTest(double[][] inputValues, out double[][] outputValues, string[] parameterList, out string[][] outLabels, bool equalVariances)
		{
			double num3;
			double num4;
			double num7;
			double num8;
			int num9;
			if (inputValues.Length != 3)
			{
				throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays);
			}
			outLabels = null;
			try
			{
				num4 = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMeanDifference);
			}
			if (num4 < 0.0)
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesNegativeMeanDifference);
			}
			try
			{
				num3 = double.Parse(parameterList[1], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			if ((num3 < 0.0) || (num3 > 1.0))
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			this.CheckNumOfPoints(inputValues);
			outputValues = new double[2][];
			outLabels = new string[][] { new string[10] };
			outputValues[0] = new double[10];
			outputValues[1] = new double[10];
			double num5 = this.Mean(inputValues[1]);
			double num6 = this.Mean(inputValues[2]);
			double num = this.Variance(inputValues[1], true);
			double num2 = this.Variance(inputValues[2], true);
			if (equalVariances)
			{
				num9 = (inputValues[1].Length + inputValues[2].Length) - 2;
				num7 = (((inputValues[1].Length - 1) * num) + ((inputValues[2].Length - 1) * num2)) / ((double)((inputValues[1].Length + inputValues[2].Length) - 2));
				num8 = ((num5 - num6) - num4) / Math.Sqrt(num7 * ((1.0 / ((double)inputValues[1].Length)) + (1.0 / ((double)inputValues[2].Length))));
			}
			else
			{
				double length = inputValues[1].Length;
				double num11 = inputValues[2].Length;
				double num12 = num;
				double num13 = num2;
				double a = (((num12 / length) + (num13 / num11)) * ((num12 / length) + (num13 / num11))) / ((((num12 / length) * (num12 / length)) / (length - 1.0)) + (((num13 / num11) * (num13 / num11)) / (num11 - 1.0)));
				num9 = (int)Math.Round(a);
				num7 = Math.Sqrt((num / ((double)inputValues[1].Length)) + (num2 / ((double)inputValues[2].Length)));
				num8 = ((num5 - num6) - num4) / num7;
			}
			double num15 = this.StudentsDistributionInverse(num3, num9);
			bool flag = num3 > 0.5;
			if (flag)
			{
				num3 = 1.0 - num3;
			}
			double num16 = this.StudentsDistributionInverse(num3 * 2.0, num9);
			if (flag)
			{
				num16 *= -1.0;
			}
			double num17 = this.StudentsDistribution(num8, num9, false);
			double num18 = this.StudentsDistribution(num8, num9, true);
			outLabels[0][0] = SR.LabelStatisticalTheFirstGroupMean;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = num5;
			outLabels[0][1] = SR.LabelStatisticalTheSecondGroupMean;
			outputValues[0][1] = 2.0;
			outputValues[1][1] = num6;
			outLabels[0][2] = SR.LabelStatisticalTheFirstGroupVariance;
			outputValues[0][2] = 3.0;
			outputValues[1][2] = num;
			outLabels[0][3] = SR.LabelStatisticalTheSecondGroupVariance;
			outputValues[0][3] = 4.0;
			outputValues[1][3] = num2;
			outLabels[0][4] = SR.LabelStatisticalTValue;
			outputValues[0][4] = 5.0;
			outputValues[1][4] = num8;
			outLabels[0][5] = SR.LabelStatisticalDegreeOfFreedom;
			outputValues[0][5] = 6.0;
			outputValues[1][5] = num9;
			outLabels[0][6] = SR.LabelStatisticalPTLessEqualSmallTOneTail;
			outputValues[0][6] = 7.0;
			outputValues[1][6] = num18;
			outLabels[0][7] = SR.LabelStatisticalSmallTCrititcalOneTail;
			outputValues[0][7] = 8.0;
			outputValues[1][7] = num16;
			outLabels[0][8] = SR.LabelStatisticalPTLessEqualSmallTTwoTail;
			outputValues[0][8] = 9.0;
			outputValues[1][8] = num17;
			outLabels[0][9] = SR.LabelStatisticalSmallTCrititcalTwoTail;
			outputValues[0][9] = 10.0;
			outputValues[1][9] = num15;
		}

		private void TTestPaired(double[][] inputValues, out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num2;
			double num3;
			if (inputValues.Length != 3)
			{
				throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays);
			}
			if (inputValues[1].Length != inputValues[2].Length)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVariableRanges);
			}
			outLabels = null;
			try
			{
				num3 = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMeanDifference);
			}
			if (num3 < 0.0)
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesNegativeMeanDifference);
			}
			try
			{
				num2 = double.Parse(parameterList[1], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			if ((num2 < 0.0) || (num2 > 1.0))
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			this.CheckNumOfPoints(inputValues);
			outputValues = new double[2][];
			outLabels = new string[][] { new string[10] };
			outputValues[0] = new double[10];
			outputValues[1] = new double[10];
			double[] values = new double[inputValues[1].Length];
			for (int i = 0; i < inputValues[1].Length; i++)
			{
				values[i] = inputValues[1][i] - inputValues[2][i];
			}
			double num6 = this.Mean(values);
			double num = Math.Sqrt(this.Variance(values, true));
			double tValue = (Math.Sqrt((double)inputValues[1].Length) * (num6 - num3)) / num;
			int n = inputValues[1].Length - 1;
			double num8 = this.StudentsDistributionInverse(num2, n);
			double num9 = (num2 <= 0.5) ? this.StudentsDistributionInverse(2.0 * num2, n) : double.NaN;
			double num10 = this.StudentsDistribution(tValue, n, false);
			double num11 = this.StudentsDistribution(tValue, n, true);
			outLabels[0][0] = SR.LabelStatisticalTheFirstGroupMean;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.Mean(inputValues[1]);
			outLabels[0][1] = SR.LabelStatisticalTheSecondGroupMean;
			outputValues[0][1] = 2.0;
			outputValues[1][1] = this.Mean(inputValues[2]);
			outLabels[0][2] = SR.LabelStatisticalTheFirstGroupVariance;
			outputValues[0][2] = 3.0;
			outputValues[1][2] = this.Variance(inputValues[1], true);
			outLabels[0][3] = SR.LabelStatisticalTheSecondGroupVariance;
			outputValues[0][3] = 4.0;
			outputValues[1][3] = this.Variance(inputValues[2], true);
			outLabels[0][4] = SR.LabelStatisticalTValue;
			outputValues[0][4] = 5.0;
			outputValues[1][4] = tValue;
			outLabels[0][5] = SR.LabelStatisticalDegreeOfFreedom;
			outputValues[0][5] = 6.0;
			outputValues[1][5] = n;
			outLabels[0][6] = SR.LabelStatisticalPTLessEqualSmallTOneTail;
			outputValues[0][6] = 7.0;
			outputValues[1][6] = num11;
			outLabels[0][7] = SR.LabelStatisticalSmallTCrititcalOneTail;
			outputValues[0][7] = 8.0;
			outputValues[1][7] = num9;
			outLabels[0][8] = SR.LabelStatisticalPTLessEqualSmallTTwoTail;
			outputValues[0][8] = 9.0;
			outputValues[1][8] = num10;
			outLabels[0][9] = SR.LabelStatisticalSmallTCrititcalTwoTail;
			outputValues[0][9] = 10.0;
			outputValues[1][9] = num8;
		}

		private double Variance(double[] values, bool sampleVariance)
		{
			if (values.Length < 1)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVarianceConditions);
			}
			double num = 0.0;
			double num2 = this.Mean(values);
			foreach (double num3 in values)
			{
				num += (num3 - num2) * (num3 - num2);
			}
			if (sampleVariance)
			{
				return (num / ((double)(values.Length - 1)));
			}
			return (num / ((double)values.Length));
		}

		private void Variance(double[][] inputValues, out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			bool flag;
			try
			{
				flag = bool.Parse(parameterList[0]);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVariance);
			}
			this.CheckNumOfPoints(inputValues);
			if (inputValues.Length != 2)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidSeriesNumber);
			}
			outLabels = null;
			outputValues = new double[2][];
			outLabels = new string[][] { new string[1] };
			outputValues[0] = new double[1];
			outputValues[1] = new double[1];
			outLabels[0][0] = SR.LabelStatisticalVariance;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = this.Variance(inputValues[1], flag);
		}

		private void ZTest(double[][] inputValues, out double[][] outputValues, string[] parameterList, out string[][] outLabels)
		{
			double num;
			double num2;
			double num3;
			double num4;
			double num11;
			if (inputValues.Length != 3)
			{
				throw new ArgumentException(SR.ExceptionPriceIndicatorsFormulaRequiresTwoArrays);
			}
			this.CheckNumOfPoints(inputValues);
			outLabels = null;
			try
			{
				num4 = double.Parse(parameterList[0], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidMeanDifference);
			}
			if (num4 < 0.0)
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesNegativeMeanDifference);
			}
			try
			{
				num = double.Parse(parameterList[1], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVariance);
			}
			try
			{
				num2 = double.Parse(parameterList[2], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidVariance);
			}
			try
			{
				num3 = double.Parse(parameterList[3], CultureInfo.InvariantCulture);
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			if ((num3 < 0.0) || (num3 > 1.0))
			{
				throw new ArgumentOutOfRangeException(SR.ExceptionStatisticalAnalysesInvalidAlphaValue);
			}
			outputValues = new double[2][];
			outLabels = new string[][] { new string[9] };
			outputValues[0] = new double[9];
			outputValues[1] = new double[9];
			double num5 = this.Mean(inputValues[1]);
			double num6 = this.Mean(inputValues[2]);
			double num7 = Math.Sqrt((num / ((double)inputValues[1].Length)) + (num2 / ((double)inputValues[2].Length)));
			double zValue = ((num5 - num6) - num4) / num7;
			double num9 = this.NormalDistributionInverse(1.0 - (num3 / 2.0));
			double num10 = this.NormalDistributionInverse(1.0 - num3);
			if (zValue < 0.0)
			{
				num11 = this.NormalDistribution(zValue);
			}
			else
			{
				num11 = 1.0 - this.NormalDistribution(zValue);
			}
			double num12 = 2.0 * num11;
			outLabels[0][0] = SR.LabelStatisticalTheFirstGroupMean;
			outputValues[0][0] = 1.0;
			outputValues[1][0] = num5;
			outLabels[0][1] = SR.LabelStatisticalTheSecondGroupMean;
			outputValues[0][1] = 2.0;
			outputValues[1][1] = num6;
			outLabels[0][2] = SR.LabelStatisticalTheFirstGroupVariance;
			outputValues[0][2] = 3.0;
			outputValues[1][2] = num;
			outLabels[0][3] = SR.LabelStatisticalTheSecondGroupVariance;
			outputValues[0][3] = 4.0;
			outputValues[1][3] = num2;
			outLabels[0][4] = SR.LabelStatisticalZValue;
			outputValues[0][4] = 5.0;
			outputValues[1][4] = zValue;
			outLabels[0][5] = SR.LabelStatisticalPZLessEqualSmallZOneTail;
			outputValues[0][5] = 6.0;
			outputValues[1][5] = num11;
			outLabels[0][6] = SR.LabelStatisticalZCriticalValueOneTail;
			outputValues[0][6] = 7.0;
			outputValues[1][6] = num10;
			outLabels[0][7] = SR.LabelStatisticalPZLessEqualSmallZTwoTail;
			outputValues[0][7] = 8.0;
			outputValues[1][7] = num12;
			outLabels[0][8] = SR.LabelStatisticalZCriticalValueTwoTail;
			outputValues[0][8] = 9.0;
			outputValues[1][8] = num9;
		}

		public virtual string Name
		{
			get
			{
				return SR.FormulaNameStatisticalAnalysis;
			}
		}
	}
}

